/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.snda.lidejia.jobflow.job;

import com.snda.lidejia.jobflow.task.MultiThreadTask;
import com.snda.lidejia.jobflow.task.SingleThreadTask;
import com.snda.lidejia.jobflow.task.Task;
import com.snda.lidejia.jobflow.task.TaskData;
import com.snda.lidejia.jobflow.task.TaskHandler;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 *
 * @author lidejia
 */
public class JobBuilder {

    public static Job buildFromXML(String jobConfigName) {
        Job job = null;
        try {
            BufferedInputStream xmlStream = new BufferedInputStream(JobBuilder.class.getResourceAsStream("/" + jobConfigName));
            try {
                SAXReader xmlReader = new SAXReader();
                xmlReader.setEncoding("UTF-8");
                Document document = xmlReader.read(xmlStream);
                job = buildFromXML(document.getRootElement());
            } finally {
                try {
                    xmlStream.close();
                } catch (IOException ex) {
                    Logger.getLogger(JobBuilder.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        } catch (DocumentException ex) {
            Logger.getLogger(JobBuilder.class.getName()).log(Level.SEVERE, null, ex);
        }
        return job;
    }

    private static Job buildFromXML(Element jobElement) {
        Element jobInputElement = jobElement.element("jobinput");
        TaskData jobInput = parseJobInput(jobInputElement);
        Job job = new Job(jobInput);
        List<Element> taskElements = jobElement.elements("task");
        for (Element taskElement : taskElements) {
            Task task = parseTask(taskElement);
            job.addTask(task);
        }
        return job;
    }

    private static TaskData parseJobInput(Element jobInputElement) {
        TaskData jobInput = new TaskData();
        List<Element> valueElements = jobInputElement.elements("value");
        for (Element valueElement : valueElements) {
            String value = valueElement.getTextTrim();
            jobInput.addData(value);
        }
        return jobInput;
    }

    private static Task parseTask(Element taskElement) {
        Task task = null;
        try {
            boolean multiThread = false;
            int threadNumber = 0;
            String multiThreadStr = taskElement.attributeValue("multithread");
            if (multiThreadStr != null && multiThreadStr.equals("true")) {
                multiThread = true;
                threadNumber = Integer.parseInt(taskElement.attributeValue("threadnum"));
            }
            String handlerClassName = taskElement.attributeValue("class");
            Class<? extends TaskHandler> handlerClass = (Class<? extends TaskHandler>) Class.forName(handlerClassName);
            if (multiThread) {
                task = new MultiThreadTask(handlerClass, threadNumber);
            } else {
                task = new SingleThreadTask(handlerClass);
            }
            List<Element> params = taskElement.elements("property");
            for (Element param : params) {
                String key = param.attributeValue("name");
                String value = param.attributeValue("value");
                task.addParam(key, value);
            }
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(JobBuilder.class.getName()).log(Level.SEVERE, null, ex);
        }
        return task;

    }
}
